﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UIShare;
using EFong.View.Proxy;
using EFong.Contract;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraTreeList;

namespace EFong.View.Security
{
    public partial class Frm_Role : BasicForm
    {
        private Proxy.BaseServiceProxy _baseProxy {get{ return Proxy.BaseServiceProxy.GetInstance();}}

        public Frm_Role()
        {
            InitializeComponent();

            this.gv_Roles.OptionsView.NewItemRowPosition = NewItemRowPosition.Top;
            this.tre_AuthroizedItems.OptionsView.ShowCheckBoxes = true;
        }

        protected override void InitFields()
        {
        }

        protected override void Events()
        {
            this.gv_Roles.InitNewRow += (s, e) =>
                {
                    Contract.Role newRole = this.gv_Roles.GetRow(e.RowHandle) as Contract.Role;

                    if (newRole != null)
                        newRole.Authorities = _baseProxy.GetRoleAuthorizedItems();
                };
            this.gv_Roles.FocusedRowChanged += (s, e) =>
                {
                    SelRole = this.gv_Roles.GetRow(e.FocusedRowHandle) as Role;
                };
            this.gv_Roles.CustomDrawCell += (s, e) =>
            {
                this.gv_Roles.CustomDrawCell<Role>(e,
                    (role) =>
                    {
                        return !role.Effective;
                    },
                    () =>
                    {
                        e.Appearance.ForeColor = Color.Red;
                    });
            };
            this.tre_AuthroizedItems.AfterCheckNode += (s, e) =>
                {
                    AuthorizedItem item = tre_AuthroizedItems.GetDataRecordByNode(e.Node) as AuthorizedItem;
                    updateRoleAuthorizedItemAllow(item, e.Node.Checked);
                };
            this.tre_AuthroizedItems.NodeChanged += (s, e) =>
                {
                    if (e.ChangeType != NodeChangeTypeEnum.Add)
                        return;

                    AuthorizedItem item = tre_AuthroizedItems.GetDataRecordByNode(e.Node) as AuthorizedItem;
                    e.Node.Checked = checkAuthorizedItemAllow(item);
                };
        }

        protected override void LoadDatas()
        {
            this.bds_Role.DataSource = _baseProxy.GetAllRole().ReturnValue;
        }

        private void bar_Main_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            switch (e.Item.Name)
            {
                case "bbt_Save":
                    this.save();
                    break;
                case "bbt_Close":
                    this.Close();
                    break;
                default:
                    break;
            }
        }

        private void save()
        {
            UIOperManager.SaveData(
                    () =>
                    {
                        this.gv_Roles.PostEditor();

                        // save change
                        return _baseProxy.UpdateRoleList(this.bds_Role.DataSource as List<Role>).IsSuccess;
                    },
                    MsgResource.Save_Complete
                );
        }

        // selected role
        private Role _selRole;
        public Role SelRole
        {
            get { return _selRole; }
            set
            {
                _selRole = value;
                onSelRoleChanged();
            }
        }

        private void onSelRoleChanged()
        {
            if (SelRole == null)
            {
                this.bds_AuthorizedItem.BindingData(null);
            }
            else
            {
                this.bds_AuthorizedItem.BindingData(_baseProxy.GetAllAuthorizedItem().ReturnValue);
            }
        }

        private bool checkAuthorizedItemAllow(AuthorizedItem item)
        {
            bool result = false;

            findMatchRoleAuthorizedItem(item,
                (roleItem) =>
                {
                    result = roleItem.Allow;
                    return true;
                });

            return result;
        }

        private void updateRoleAuthorizedItemAllow(AuthorizedItem item, bool value)
        {
            findMatchRoleAuthorizedItem(item,
                (roleItem) =>
                {
                    roleItem.Allow = value;
                    return true;
                });
        }

        private void findMatchRoleAuthorizedItem(AuthorizedItem item, Func<RoleAuthorizedItem, bool> findedAction)
        {
            if (SelRole == null)
                return;

            foreach (var roleItem in SelRole.Authorities)
            {
                if (roleItem.AuthorizedItem.ID == item.ID)
                {
                    bool result = findedAction.Invoke(roleItem);

                    if (result)
                        return;
                }
            }
        }
    }
}
